package com.xq.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.xq.filter.AppFilter;
import com.xq.interceptor.MyInterceptor;
import com.xq.listener.AppListener;
import com.xq.servelt.UserServlet;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * @author xq
 * @version 1.0
 * @date 2021/4/17 16:00
 * @description web的配置类
 */
@Configuration
@Component
@ConfigurationProperties(prefix = "web")
@Data
public class WebMvcConfig implements WebMvcConfigurer {
    /**
     * 是否开启监听器，默认开启
     */
    private Boolean appListenerEnable = true;

    /**
     * 当页面跳转时，我们需要在Controller里面创建一个空方法去跳转
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // index/hello --> IndexController --> template/hello
        // 请求转发
        registry.addViewController("/index")
                .setViewName("index");
        // 请求重定向
        registry.addRedirectViewController("/index/teacherList","/teacherList.html");
    }

    /**
     * 自定义日期格式化器
     * @param registry
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new Formatter<Date>() {
            /**
             * 日期格式化
             */
            @Override
            public Date parse(String text, Locale locale) throws ParseException {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return format.parse(text);
            }
            @Override
            public String print(Date date, Locale locale) {
                return null;
            }
        });
    }

    /**
     * 自定义扩展消息转化器 [平时不配，因为有jaskson的转化器]
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 创建阿里巴巴的fastJson转换对象
        FastJsonHttpMessageConverter fc = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        // 设置序列化器功能
        config.setSerializerFeatures(SerializerFeature.PrettyFormat);
        // 设置阿里巴巴的配置
        fc.setFastJsonConfig(config);
        // 处理中文乱码，在前端出现的
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        // 添加阿里巴巴消息转换器
        converters.add(fc);
    }
    /**
     * 添加拦截器的方法
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        MyInterceptor interceptor = new MyInterceptor();
        registry.addInterceptor(interceptor)
                // 配置拦截的路径
                .addPathPatterns("/**")
                // 配置不拦截的路径
                .excludePathPatterns("/index/show*");
    }

    /**
     * 创建UserServlet
     * @return
     */
    @Bean("userServlet")
    @ConditionalOnClass(value = {UserServlet.class})
    public UserServlet userServlet() {
        return new UserServlet();
    }

    /**
     * 注册UserServlet
     */
    @Bean
    @ConditionalOnClass(value = {UserServlet.class})
    public ServletRegistrationBean<UserServlet> servletServletRegistrationBean(UserServlet userServlet) {
        // 创建注册器对象
        ServletRegistrationBean<UserServlet> registrationBean = new ServletRegistrationBean<>();
        // 注入Servlet
        registrationBean.setServlet(userServlet);
        // 设置参数
        registrationBean.addInitParameter("env","UTF-8");
        registrationBean.addInitParameter("hello","你好");
        // 设置映射
        registrationBean.addUrlMappings("/index/showStudent","/*");
        return registrationBean;
    }

    /**
     * 创建过滤器(filter)
     * @return
     */
    @Bean("appFilter")
    @ConditionalOnClass(value = {AppFilter.class})
    public AppFilter appFilter() {
        return new AppFilter();
    }

    /**
     * 注册过滤器(filter)
     * @param appFilter
     * @return
     */
    @Bean
    @ConditionalOnClass(value = {AppFilter.class})
    public FilterRegistrationBean<AppFilter> filterFilterRegistrationBean(AppFilter appFilter) {
        // 创建注册器
        FilterRegistrationBean<AppFilter> registrationBean = new FilterRegistrationBean<>();
        // 注入filter
        registrationBean.setFilter(appFilter);
        // 设置参数
        registrationBean.addInitParameter("env","UTF-8");
        registrationBean.addInitParameter("hello","你好");
        // 设置映射
        //registrationBean.addUrlPatterns("/index/showStudent","/*");
        registrationBean.addServletNames("userServlet");
        return registrationBean;
    }

    /**
     * 创建监听器(listener)
     * @return
     */
    @Bean
    @ConditionalOnClass(value = {AppListener.class})
    public AppListener appListener() {
        return new AppListener();
    }

    /**
     * 注册监听器(listener)
     * @param appListener
     * @return
     */
    @Bean
    @ConditionalOnClass(value = {AppListener.class})
    public ServletListenerRegistrationBean<AppListener> servletListenerRegistrationBean(AppListener appListener) {
        // 创建注册器
        ServletListenerRegistrationBean<AppListener> registrationBean = new ServletListenerRegistrationBean<>();
        // 注入监听器
        registrationBean.setListener(appListener);
        // 开启监听器
        registrationBean.setEnabled(this.appListenerEnable);
        return registrationBean;
    }
}
